---
title: "ecolRxC accuracy with Thomsen, logit and with Yule aproximation"
author: " "
date: ' '
output: html_document
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```

## Note

The packages **ei.Datasets** and **ecolRxC** need to be installed to this code to run. 

## Introduction

This document summarises the accuracy of the estimates attained with the function **ecolRxC()** of the **ecolRxC** package with arguments `method = "Thomsen"`, `scale = "logit"` and `Yule.aprox = TRUE` when applied to the datasets available in **ei.Datasets**.

The cross-distribution matrices are estimated at the constituency level for the 2007 Scottish Parliamentary Elections (Scottish Parliamentary Elections, May 3, 2007), 73 matrices, using the data available in the object ei_SCO_2007 and the 2002-2020 NZ elections, 492 matrices, available in the ei_NZ_ objects.

All in all, a total of 565 transfer matrices are estimated, for which the true transfer matrices are known. The comparison with the real values is made using the error and the discrepancy and quadratic indexes (see following equations), which are calculated by the **EI()**, **EPW()** and **EQ()**  functions. The number of voting matrices for each election is detailed in the attached table.

| Elección | Número de matrices |
|:--------:|:----------------:|
| 2020     |   72             | 
| 2017     |   71             |  
| 2014     |   71             |  
| 2011     |   70             |  
| 2008     |   70             |  
| 2007     |   73             | 
| 2005     |   69             |  
| 2002     |   69             |  


Regarding the election options considered in votes for parties and in votes for candidates, this study is based on imposing having obtained a minimum of **3%** of the votes. Those options that did not overcome this barrier have been grouped under the "others" option. Likewise, parties are considered in rows and candidates in columns.


## Notation

- $x_{ij}$ votes gained in unit *i* by party *j* (*j = 1,...,J*, *i = 1,...,I*).
- $y_{ik}$ votes obtained in unit *i* by candidate *k* (*k = 1,...,K*, *i = 1,...,I*).
- $v_{jk}$ voters in the district who choose party *j* and candidate *k*.
- $v^{*}_{jk}$ estimate of the number of voters in the district who choose party *j* and candidate *k*.
- $v_{j.} = \sum_{k=1}^{K}v_{jk} = \sum_{i=1}^{I}x_{ij}$ number of voters in the district who choose party *j*.
- $v_{.k} = \sum_{j=1}^{J}v_{jk} = \sum_{i=1}^{I}y_{ik}$ number of voters in the district who choose candidate *k*.
- $x_{i.} = \sum_{j=1}^{J}v_{ij} = \sum_{k=1}^{K}y_{ik} = y_{i.}$ number of voters in electoral unit *i*.
- $p_{jk}$ proportion of voters in the district who choose candidate *k* among those who chose party *j*,
$p_{jk} = v_{jk}/v_{j.} = p_{k|j}$
- $p^{*}_{jk}$ estimate proportion of voters in the district who choose candidate *k* among those who chose party *j*, $p^{*}_{jk} = v^{*}_{jk}/v_{j.} = p^{*}_{k|j}$
- $p_{j.}$ proportion of voters in the district who choose party *j*, $p_{j.} = \frac{v_{j.}}{\sum_{j}v_{j.}}$
- $p_{.k}$ proportion of voters in the district who choose candidate *k*: $p_{.k} = \frac{v_{.k}}{\sum_{k}v_{.k}}$



## **EI()** Error-index, **EPW()** Discrepancy-index and **EQ()** Quadratic- index.

The accuracy of the estimates is assessed by comparing actual and estimates values using the Error Index:

$EI = 100\frac{0.5\sum_{j,k}|v_{jk}-v_{jk}^{*}|}{\sum_{j,k}v_{jk}}$

$EPW = 100\frac{\sum_{j,k} v_{jk}|p_{jk}-p_{jk}^{*}|}{\sum_{j,k} v_{jk}}$

$EQ = 100\frac{\sqrt{\sum_{j,k} (v_{jk}-v_{jk}^{*})^{2}}}{\sum_{j,k}v_{jk}}$

- $v_{jk}$ voters in the district who choose party *j* and candidate *k*.
- $v^{*}_{jk}$ estimate of the number of voters in the district who choose party *j* and candidate *k*.
- $p_{jk}$ proportion of voters in the district who choose candidate *k* among those who chose party *j* .
- $p^{*}_{jk}$ estimate of the proportion of voters in the district who choose candidate *k* among those who chose party *j* .

```{r}
EI <- function(real, estimada, marginal){
  real <- real/rowSums(real)*marginal
  estimada <- estimada/rowSums(estimada)*marginal
  output <- 100*sum(abs(real - estimada))*.5/sum(marginal)
  return(output)
}
```

```{r}
EPW <- function(real, estimada, marginal){
  real <- real/rowSums(real)
  estimada <- estimada/rowSums(estimada)
  output <- 100*sum(real*marginal*abs(real - estimada))/sum(marginal)
  return(output)
}

```

```{r}
EQ <- function(real, estimada, marginal){
  real <- real/rowSums(real)*marginal
  estimada <- estimada/rowSums(estimada)*marginal
  output <- 100*sqrt(sum((real - estimada)^2))/sum(marginal)
  return(output)
}
```

## Summary statistics

#### summary_ecolRxC_solutions_Thomsen_logit_TRUE.csv

To assess the accuracy of the solutions, a battery of statistics is kept:

* **year**: *year* to which the estimated-actual comparison corresponds.
* **district**: Name of the district for which estimates belong to.
* **EI.ecolRxC.Mean**: *error index*, coefficient *EI* obtained for simple mean average solution, attained after combining with equal weights the solutions obtained using the different combinations of a row and a column option as reference.
* **EI.ecolRxC.RCNV**: *error index*, coefficient *EI* obtained for the mean average solution attained after combining with different weights the solutions obtained using the different combinations of a row and a column option as reference, using as weights the global (crude) number of voters in the reference cells.
* **EI.ecolRxC.SQRCNV**: *error index*, coefficient *EI* obtained for the mean average solution attained after combining with different weights the solutions obtained using the different combinations of a row and a column option as reference, using as weights the global square root of the (crude) number of voters in the reference cells. 
* **EI.ecolRxC.SQRM**: *error index*, coefficient *EI* obtained for the mean average solution attained after combining with different weights the solutions obtained using the different combinations of a row and a column option as reference, using as weights the global square root of the product of the observed margins corresponding to the reference cells. 
* **EI.ecolRxC.AVCR**: *error index*, coefficient *EI* obtained for the mean average solution attained after combining with equal weights the solutions obtained using the different combinations of a row and a column option as reference, using as weights the absolute values of reference correlations.
* **EI.ecolRxC.LRCNV**: *error index*, coefficient *EI* obtained for the mean average solution attained after combining with different weights the solutions obtained using the different combinations of a row and a column option as reference, using as weights the local (crude) number of voters in the reference cells.
* **EI.ecolRxC.LSQRCNV**: *error index*, coefficient *EI* obtained for the mean average solution attained after combining with different weights the solutions obtained using the different combinations of a row and a column option as reference, using as weights the local square root of the (crude) number of voters in the reference cells. 
* **EI.ecolRxC.LSQRM**: *error index*, coefficient *EI* obtained for the mean average solution attained after combining with different weights the solutions obtained using the different combinations of a row and a column option as reference, using as weights the local square root of the product of the observed margins corresponding to the reference cells.
* **EI.ecolRxC.Average**: *error index*, average of *EI* coefficients after computing the *EI* coefficient for each of the solutions that is attained using each combination of a row and a column option as reference.


* **EPW.ecolRxC.Mean**: *discrepancy index*, coefficient *EPW* obtained for simple mean average solution, attained after combining with equal weights the solutions obtained using the different combinations of a row and a column option as reference.
* **EPW.ecolRxC.RCNV**: *discrepancy index*, coefficient *EPW* obtained for the mean average solution attained after combining with different weights the solutions obtained using the different combinations of a row and a column option as reference, using as weights the global (crude) number of voters in the reference cells.
* **EPW.ecolRxC.SQRCNV**: *discrepancy index*, coefficient *EPW* obtained for the mean average solution attained after combining with different weights the solutions obtained using the different combinations of a row and a column option as reference, using as weights the global square root of the (crude) number of voters in the reference cells. 
* **EPW.ecolRxC.SQRM**: *discrepancy index*, coefficient *EPW* obtained for the mean average solution attained after combining with different weights the solutions obtained using the different combinations of a row and a column option as reference, using as weights the global square root of the product of the observed margins corresponding to the reference cells. 
* **EPW.ecolRxC.AVCR**: *discrepancy index*, coefficient *EPW* obtained for the mean average solution attained after combining with equal weights the solutions obtained using the different combinations of a row and a column option as reference, using as weights the absolute values of reference correlations.
* **EPW.ecolRxC.LRCNV**: *discrepancy index*, coefficient *EPW* obtained for the mean average solution attained after combining with different weights the solutions obtained using the different combinations of a row and a column option as reference, using as weights the local (crude) number of voters in the reference cells.
* **EPW.ecolRxC.LSQRCNV**: *discrepancy index*, coefficient *EPW* obtained for the mean average solution attained after combining with different weights the solutions obtained using the different combinations of a row and a column option as reference, using as weights the local square root of the (crude) number of voters in the reference cells. 
* **EPW.ecolRxC.LSQRM**: *discrepancy index*, coefficient *EPW* obtained for the mean average solution attained after combining with different weights the solutions obtained using the different combinations of a row and a column option as reference, using as weights the local square root of the product of the observed margins corresponding to the reference cells.
* **EPW.ecolRxC.Average**: *discrepancy index*, average of *EPW* coefficients after computing the *EPW* coefficient for each of the solutions that is attained using each combination of a row and a column option as reference.

* **EQ.ecolRxC.Mean**: coefficient *EQ* obtained for the simple mean average solution, attained after combining with equal weights the solutions obtained using the different combinations of a row and a column option as reference.
* **EQ.ecolRxC.RCNV**: coefficient *EQ obtained for the mean average solution attained after combining with different weights the solutions obtained using the different combinations of a row and a column option as reference, using as weights the global (crude) number of voters in the reference cells.
* **EQ.ecolRxC.SQRCNV**: coefficient *EQ* obtained for the mean average solution attained after combining with different weights the solutions obtained using the different combinations of a row and a column option as reference, using as weights the global square root of the (crude) number of voters in the reference cells. 
* **EQ.ecolRxC.SQRM**: coefficient *EPW* obtained for the mean average solution attained after combining with different weights the solutions obtained using the different combinations of a row and a column option as reference, using as weights the global square root of the product of the observed margins corresponding to the reference cells. 
* **EQ.ecolRxC.AVCR**: coefficient *EQ* obtained for the mean average solution attained after combining with equal weights the solutions obtained using the different combinations of a row and a column option as reference, using as weights the absolute values of reference correlations.
* **EQ.ecolRxC.LRCNV**: coefficient *EQ* obtained for the mean average solution attained after combining with different weights the solutions obtained using the different combinations of a row and a column option as reference, using as weights the local (crude) number of voters in the reference cells.
* **EQ.ecolRxC.LSQRCNV**: coefficient *EQ* obtained for the mean average solution attained after combining with different weights the solutions obtained using the different combinations of a row and a column option as reference, using as weights the local square root of the (crude) number of voters in the reference cells. 
* **EQ.ecolRxC.LSQRM**: coefficient *EQ* obtained for the mean average solution attained after combining with different weights the solutions obtained using the different combinations of a row and a column option as reference, using as weights the local square root of the product of the observed margins corresponding to the reference cells.
* **EQ.ecolRxC.Average**: average of *EQ* coefficients after computing the *EQ* coefficient for each of the solutions that is attained using each combination of a row and a column option as reference.

In order to evaluate computational costs, the time that each algorithm spends in reaching the estimate is also computed.

* **time.ecolRxC.logit.Thomsen.T**: computation time (in secs) spent by the **ecolRxC()** function  with arguments `method = "Thomsen"`, `scale="logit"` and `Yule.aprox = TRUE`.


#### pjk_ecolRxC_predictions_Thomsen_logit_TRUE.csv

* **year**: *year* to which the estimated-actual comparison corresponds.
* **district**: Name of the district for which estimates belong to.
* **votes**: *total de votes* recorded in *district* in the election held in *year*.
* **I**: *number of units* (polling stations) of the district.
* **row**: row *j* linked to estimate *p~jk~* of the transfer matrix.
* **column**: column *k* linked to estimate *p~jk~* of the transfer matrix.
* **pjk**: Actual value corresponding to *p~jk~*.
* **vjk**: Actual value corresponding to *v~jk~*.
* **pjk.ecolRxC.Mean**: percentage of vote transfer estimate from party *j* to candidate *k* obtained for simple mean average solution, attained after combining with equal weights the solutions obtained using the different combinations of a row and a column option as reference.
* **pjk.ecolRxC.RCNV**: percentage of vote transfer estimate from party *j* to candidate *k*  attained after combining with different weights the solutions obtained using the different combinations of a row and a column option as reference, using as weights the global (crude) number of voters in the reference cells.
* **pjk.ecolRxC.SQRCNV**: percentage of vote transfer estimate from party *j* to candidate *k*  attained after combining with different weights the solutions obtained using the different combinations of a row and a column option as reference, using as weights the global square root of the (crude) number of voters in the reference cells.
* **pjk.ecolRxC.SQRM**: percentage of vote transfer estimate from party *j* to candidate *k*  attained after combining with different weights the solutions obtained using the different combinations of a row and a column option as reference, using as weights the global square root of the product of the observed margins corresponding to the reference cells. 
* **pjk.ecolRxC.AVCR**: percentage of vote transfer estimate from party *j* to candidate *k*  attained after combining with different weights the solutions obtained using the different combinations of a row and a column option as reference,  using as weights the absolute values of reference correlations.
* **pjk.ecolRxC.LRCNV**: percentage of vote transfer estimate from party *j* to candidate *k*  attained after combining with different weights the solutions obtained using the different combinations of a row and a column option as reference, using as weights the local (crude) number of voters in the reference cells.
* **pjk.ecolRxC.LSQRCNV**: percentage of vote transfer estimate from party *j* to candidate *k*  attained after combining with different weights the solutions obtained using the different combinations of a row and a column option as reference, using as weights the local square root of the (crude) number of voters in the reference cells.
* **pjk.ecolRxC.LSQRM**: percentage of vote transfer estimate from party *j* to candidate *k*  attained after combining with different weights the solutions obtained using the different combinations of a row and a column option as reference, using as weights the local square root of the product of the observed margins corresponding to the reference cells. 
* **EI.ecolRxC.refjk**: Error index linked to the solution attained when party *j* and candidate *k* are used as references. 
* **EPW.ecolRxC.refjk**: Discrepancy index linked to the solution attained when party *j* and candidate *k* are used as references. 
* **EQ.ecolRxC.refjk**: EQ indices linked to the solution attained when party *j* and candidate *k* are used as references. 
* **correlationsjk**: Estimated correlations between the vote share proportion transformations of party *j* and candidate *k*. 

## CODE OF COMPUTATION.

```{r, message = F, warning = F}
library(ecolRxC)
library(ei.Datasets)
```

```{r}
sessionInfo()
```

```{r}
year <- district <- EI.ecolRxC.Mean <- EI.ecolRxC.RCNV <- EI.ecolRxC.SQRCNV <- EI.ecolRxC.SQRM <-
  EI.ecolRxC.AVCR <- EI.ecolRxC.LRCNV <- EI.ecolRxC.LSQRCNV <- EI.ecolRxC.LSQRM <- EI.ecolRxC.Average <-
  EPW.ecolRxC.Mean <- EPW.ecolRxC.RCNV <- EPW.ecolRxC.SQRCNV <- EPW.ecolRxC.SQRM <-
  EPW.ecolRxC.AVCR <- EPW.ecolRxC.LRCNV <- EPW.ecolRxC.LSQRCNV <- EPW.ecolRxC.LSQRM <- EPW.ecolRxC.Average <- EQ.ecolRxC.Mean <- EQ.ecolRxC.RCNV <- EQ.ecolRxC.SQRCNV <-
  EQ.ecolRxC.SQRM <- EQ.ecolRxC.AVCR <- EQ.ecolRxC.LRCNV <- EQ.ecolRxC.LSQRCNV <-
  EQ.ecolRxC.LSQRM <- EQ.ecolRxC.Average <-
  time.ecolRxC.logit.Thomsen.T <- NULL

year2 <- district2 <- votes2 <- I2 <- row <- column <- pjk <- vjk <- pjk.ecolRxC.Mean <- pjk.ecolRxC.RCNV <- pjk.ecolRxC.SQRCNV <- pjk.ecolRxC.SQRM <- pjk.ecolRxC.AVCR <- pjk.ecolRxC.LRCNV <- pjk.ecolRxC.LSQRCNV <- pjk.ecolRxC.LSQRM <-  EI.ecolRxC.refjk <- EPW.ecolRxC.refjk <- EQ.ecolRxC.refjk <- correlationsjk <- NULL
```


```{r elecciones, message = F, warning = F}
bases <- c("ei_NZ_2002", "ei_NZ_2005", "ei_SCO_2007", "ei_NZ_2008", "ei_NZ_2011", "ei_NZ_2014",
           "ei_NZ_2017", "ei_NZ_2020")

for (bb in 1:length(bases)){

base.datos <- merge_small_options(get(bases[bb]), 3, 3)
anyo <- substr(bases[bb], nchar(bases[bb])-3, 999)

for (dd in 1:nrow(base.datos)){
    # Reading the data
    cruzada <- base.datos$District_cross_votes[[dd]]
    candidatos <-  base.datos$Votes_to_candidates[[dd]]
    names(candidatos) <- paste0(names(candidatos), ".c")
    partidos <-  base.datos$Votes_to_parties[[dd]]
    names(partidos) <- paste0(names(partidos), ".p")
    district0 <-  base.datos$District[dd]
    
    # Get rid off metadata of the objects
    cruzada <- cruzada[, -1]
    candidatos <- candidatos[, -c(1,2)]
    partidos <- partidos[, -c(1,2)]
    votos.p <- colSums(partidos)
    votos.c <- colSums(candidatos)
    votos.real <- cruzada
    prop.real <- votos.real/rowSums(votos.real)
    
    # To save pjk
    grid <- cbind(expand.grid(1:ncol(cruzada), 1:nrow(cruzada)))
    colnames(grid) <- c("row", "column")
    prob.real2 <- round(as.vector(as.matrix(t(prop.real*100))), 2)
    votos.real <- as.vector(t(as.matrix(round(cruzada))))
    
    #-------------------------------------------------
    # ecolRxC logit Thomsen TRUE
    start.1 <- Sys.time()
      trans1 <- ecolRxC(partidos, candidatos, scale = "logit", method = "Thomsen", 
                        Yule.aprox = TRUE, confidence = NULL)
    end.1 <- Sys.time()
    
    error.1 <- EI(prop.real, trans1$reference.outputs$vjk.averages[, , 1], colSums(partidos))
    error.2 <- EI(prop.real, trans1$reference.outputs$vjk.averages[, , 2], colSums(partidos))
    error.3 <- EI(prop.real, trans1$reference.outputs$vjk.averages[, , 3], colSums(partidos))
    error.4 <- EI(prop.real, trans1$reference.outputs$vjk.averages[, , 4], colSums(partidos))
    error.5 <- EI(prop.real, trans1$reference.outputs$vjk.averages[, , 5], colSums(partidos))
    error.6 <- EI(prop.real, trans1$reference.outputs$vjk.averages[, , 6], colSums(partidos))
    error.7 <- EI(prop.real, trans1$reference.outputs$vjk.averages[, , 7], colSums(partidos))
    error.8 <- EI(prop.real, trans1$reference.outputs$vjk.averages[, , 8], colSums(partidos))
    discr.1 <- EPW(prop.real, trans1$reference.outputs$vjk.averages[, , 1], colSums(partidos))
    discr.2 <- EPW(prop.real, trans1$reference.outputs$vjk.averages[, , 2], colSums(partidos))
    discr.3 <- EPW(prop.real, trans1$reference.outputs$vjk.averages[, , 3], colSums(partidos))
    discr.4 <- EPW(prop.real, trans1$reference.outputs$vjk.averages[, , 4], colSums(partidos))
    discr.5 <- EPW(prop.real, trans1$reference.outputs$vjk.averages[, , 5], colSums(partidos))
    discr.6 <- EPW(prop.real, trans1$reference.outputs$vjk.averages[, , 6], colSums(partidos))
    discr.7 <- EPW(prop.real, trans1$reference.outputs$vjk.averages[, , 7], colSums(partidos))
    discr.8 <- EPW(prop.real, trans1$reference.outputs$vjk.averages[, , 8], colSums(partidos))
    eq.1 <- EQ(prop.real, trans1$reference.outputs$vjk.averages[, , 1], colSums(partidos))
    eq.2 <- EQ(prop.real, trans1$reference.outputs$vjk.averages[, , 2], colSums(partidos))
    eq.3 <- EQ(prop.real, trans1$reference.outputs$vjk.averages[, , 3], colSums(partidos))
    eq.4 <- EQ(prop.real, trans1$reference.outputs$vjk.averages[, , 4], colSums(partidos))
    eq.5 <- EQ(prop.real, trans1$reference.outputs$vjk.averages[, , 5], colSums(partidos))
    eq.6 <- EQ(prop.real, trans1$reference.outputs$vjk.averages[, , 6], colSums(partidos))
    eq.7 <- EQ(prop.real, trans1$reference.outputs$vjk.averages[, , 7], colSums(partidos))
    eq.8 <- EQ(prop.real, trans1$reference.outputs$vjk.averages[, , 8], colSums(partidos))

    error.a <- discr.a <- eq.a <-NULL
    for (ee in 1:nrow(grid)){
      sol <- trans1$reference.outputs$vjk.by.reference[, , ee]
      error.a <- c(error.a, EI(prop.real, sol, colSums(partidos)))
      discr.a <- c(discr.a, EPW(prop.real, sol, colSums(partidos)))
      eq.a <- c(eq.a, EQ(prop.real, sol, colSums(partidos)))
    }
    time.1 <- round(as.numeric(difftime(end.1, start.1, units = "secs")), 2)
    #-------------------------------------------------
    
    # Saving outputs summary_ecolRxC_solutions_Thomsen_logit_TRUE.csv
    year <- c(year, anyo)
    district <- c(district, district0)
    
    EI.ecolRxC.Mean <- c(EI.ecolRxC.Mean, error.1) 
    EI.ecolRxC.RCNV <- c(EI.ecolRxC.RCNV, error.2)
    EI.ecolRxC.SQRCNV <- c(EI.ecolRxC.SQRCNV, error.3) 
    EI.ecolRxC.SQRM <- c(EI.ecolRxC.SQRM, error.4)
    EI.ecolRxC.AVCR <- c(EI.ecolRxC.AVCR, error.5) 
    EI.ecolRxC.LRCNV <- c(EI.ecolRxC.LRCNV, error.6) 
    EI.ecolRxC.LSQRCNV <- c(EI.ecolRxC.LSQRCNV, error.7) 
    EI.ecolRxC.LSQRM <- c(EI.ecolRxC.LSQRM, error.8)
    EI.ecolRxC.Average <- c(EI.ecolRxC.Average, mean(error.a))

    EPW.ecolRxC.Mean <- c(EPW.ecolRxC.Mean, discr.1) 
    EPW.ecolRxC.RCNV <- c(EPW.ecolRxC.RCNV, discr.2)
    EPW.ecolRxC.SQRCNV <- c(EPW.ecolRxC.SQRCNV, discr.3) 
    EPW.ecolRxC.SQRM <- c(EPW.ecolRxC.SQRM, discr.4)
    EPW.ecolRxC.AVCR <- c(EPW.ecolRxC.AVCR, discr.5) 
    EPW.ecolRxC.LRCNV <- c(EPW.ecolRxC.LRCNV, discr.6) 
    EPW.ecolRxC.LSQRCNV <- c(EPW.ecolRxC.LSQRCNV, discr.7) 
    EPW.ecolRxC.LSQRM <- c(EPW.ecolRxC.LSQRM, discr.8)
    EPW.ecolRxC.Average <- c(EPW.ecolRxC.Average, mean(discr.a))

    EQ.ecolRxC.Mean <- c(EQ.ecolRxC.Mean, eq.1) 
    EQ.ecolRxC.RCNV <- c(EQ.ecolRxC.RCNV, eq.2)
    EQ.ecolRxC.SQRCNV <- c(EQ.ecolRxC.SQRCNV, eq.3) 
    EQ.ecolRxC.SQRM <- c(EQ.ecolRxC.SQRM, eq.4)
    EQ.ecolRxC.AVCR <- c(EQ.ecolRxC.AVCR, eq.5) 
    EQ.ecolRxC.LRCNV <- c(EQ.ecolRxC.LRCNV, eq.6) 
    EQ.ecolRxC.LSQRCNV <- c(EQ.ecolRxC.LSQRCNV, eq.7) 
    EQ.ecolRxC.LSQRM <- c(EQ.ecolRxC.LSQRM, eq.8)
    EQ.ecolRxC.Average <- c(EQ.ecolRxC.Average, mean(eq.a))

    time.ecolRxC.logit.Thomsen.T <- c(time.ecolRxC.logit.Thomsen.T, time.1)

    tabla.resumen <- data.frame(year, district, EI.ecolRxC.Mean, EI.ecolRxC.RCNV,
                                EI.ecolRxC.SQRCNV, EI.ecolRxC.SQRM, EI.ecolRxC.AVCR,
                                EI.ecolRxC.LRCNV, EI.ecolRxC.LSQRCNV, EI.ecolRxC.LSQRM,
                                EI.ecolRxC.Average,
                                EPW.ecolRxC.Mean, EPW.ecolRxC.RCNV, EPW.ecolRxC.SQRCNV,
                                EPW.ecolRxC.SQRM, EPW.ecolRxC.AVCR, EPW.ecolRxC.LRCNV,
                                EPW.ecolRxC.LSQRCNV, EPW.ecolRxC.LSQRM,
                                EPW.ecolRxC.Average, 
                                EQ.ecolRxC.Mean, EQ.ecolRxC.RCNV, EQ.ecolRxC.SQRCNV,
                                EQ.ecolRxC.SQRM, EQ.ecolRxC.AVCR, EQ.ecolRxC.LRCNV,
                                EQ.ecolRxC.LSQRCNV, EQ.ecolRxC.LSQRM,
                                EQ.ecolRxC.Average, 
                                time.ecolRxC.logit.Thomsen.T)
    write.table(tabla.resumen, file = "summary_ecolRxC_solutions_Thomsen_logit_TRUE.csv", 
                sep =";", row.names = F)
    
    # Saving outputs pjk_ecolRxC_predictions_Thomsen_logit_TRUE.csv
    year2 <- c(year2, rep(anyo, length(votos.real)))
    district2 <- c(district2, rep(district0, length(votos.real)))
    votes2 <- c(votes2, rep(sum(partidos), length(votos.real)))
    I2 <- c(I2, rep(nrow(partidos), length(votos.real)))
    row <- c(row, grid[,2])
    column <- c(column, grid[,1])
    pjk <- c(pjk, prob.real2)
    vjk <- c(vjk, votos.real)
    pjk.ecolRxC.Mean <- c(pjk.ecolRxC.Mean,
       round(as.vector(t(as.matrix(
             trans1$reference.outputs$vjk.averages[, , 1]/colSums(partidos))))*100, 2))
    pjk.ecolRxC.RCNV <- c(pjk.ecolRxC.RCNV,
       round(as.vector(t(as.matrix(
             trans1$reference.outputs$vjk.averages[, , 2]/colSums(partidos))))*100, 2))
    pjk.ecolRxC.SQRCNV <- c(pjk.ecolRxC.SQRCNV,
       round(as.vector(t(as.matrix(
             trans1$reference.outputs$vjk.averages[, , 3]/colSums(partidos))))*100, 2))
    pjk.ecolRxC.SQRM <- c(pjk.ecolRxC.SQRM,
       round(as.vector(t(as.matrix(
             trans1$reference.outputs$vjk.averages[, , 4]/colSums(partidos))))*100, 2))
    pjk.ecolRxC.AVCR <- c(pjk.ecolRxC.AVCR,
       round(as.vector(t(as.matrix(
             trans1$reference.outputs$vjk.averages[, , 5]/colSums(partidos))))*100, 2))
    pjk.ecolRxC.LRCNV <- c(pjk.ecolRxC.LRCNV,
       round(as.vector(t(as.matrix(
             trans1$reference.outputs$vjk.averages[, , 6]/colSums(partidos))))*100, 2))
    pjk.ecolRxC.LSQRCNV <- c(pjk.ecolRxC.LSQRCNV,
       round(as.vector(t(as.matrix(
             trans1$reference.outputs$vjk.averages[, , 7]/colSums(partidos))))*100, 2))
    pjk.ecolRxC.LSQRM <- c(pjk.ecolRxC.LSQRM,
       round(as.vector(t(as.matrix(
             trans1$reference.outputs$vjk.averages[, , 8]/colSums(partidos))))*100, 2))
    EI.ecolRxC.refjk <- c(EI.ecolRxC.refjk, round(error.a, 2))
    EPW.ecolRxC.refjk <- c(EPW.ecolRxC.refjk, round(discr.a, 2))
    EQ.ecolRxC.refjk <- c(EQ.ecolRxC.refjk, round(eq.a, 2))
    correlationsjk <- c(correlationsjk, as.vector(t(trans1$correlations)))
    
    tabla.resumen2 <- data.frame(year = year2, district = district2, votes = votes2, 
                                 I = I2, row, column, vjk, pjk, pjk.ecolRxC.Mean, pjk.ecolRxC.RCNV,
                                 pjk.ecolRxC.SQRCNV, pjk.ecolRxC.SQRM, pjk.ecolRxC.AVCR,
                                 pjk.ecolRxC.LRCNV, pjk.ecolRxC.LSQRCNV, pjk.ecolRxC.LSQRM,
                                 EI.ecolRxC.refjk, EPW.ecolRxC.refjk, 
                                 EQ.ecolRxC.refjk, correlationsjk)
    
    write.table(tabla.resumen2, file = "pjk_ecolRxC_predictions_Thomsen_logit_TRUE.csv", 
                sep =";", row.names = F)
 }
}
```


